﻿using System.Services;
using System.Threading.Tasks;
using Windows.Devices.Sensors;

namespace System.Sensors
{
    public interface IAccelerometerSensorService : ISensorService<Accelerometer, AccelerometerReading>
    {
    }

    [ExportService("AccelerometerSensorService", "", typeof(IAccelerometerSensorService), int.MaxValue)]
    public class AccelerometerSensorService : SensorServiceBase<Accelerometer, AccelerometerReading>, IAccelerometerSensorService
    {
        public AccelerometerSensorService()
        {
        }

        public override void StartService()
        {
            Sensor = Accelerometer.GetDefault();
            base.StartService();
        }

        public override void Subscribe()
        {
            if (IsSensorAvailable)
            {
                Sensor.ReadingChanged += Sensor_ReadingChanged;
                Sensor.Shaken += Sensor_Shaken;
            }

            base.Subscribe();
        }

        public override void Unsubscribe()
        {
            if (IsSensorAvailable)
            {
                Sensor.ReadingChanged -= Sensor_ReadingChanged;
                Sensor.Shaken -= Sensor_Shaken;
            }

            base.Unsubscribe();
        }

        void Sensor_ReadingChanged(Accelerometer sender, AccelerometerReadingChangedEventArgs args)
        {
            if (EventAggregator != null)
                EventAggregator.Publish<AccelerometerServiceReadingMessage>(new AccelerometerServiceReadingMessage(this, args.Reading));
        }

        void Sensor_Shaken(Accelerometer sender, AccelerometerShakenEventArgs args)
        {
            if (EventAggregator != null)
                EventAggregator.Publish<AccelerometerShakenMessage>(new AccelerometerShakenMessage(this, args.Timestamp));
        }

        protected override async Task<AccelerometerReading> GetSensorData()
        {
            return Sensor.GetCurrentReading();
        }

        public override uint GetMinimumReportInterval()
        {
            return Sensor.MinimumReportInterval;
        }

        public override uint GetReportInterval()
        {
            return Sensor.ReportInterval;
        }

        public override void SetReportInterval(uint value)
        {
            Sensor.ReportInterval = value;
        }
    }

    public class AccelerometerServiceReadingMessageBase<T> : SensorReadingMessageBase<T>
    {
        public AccelerometerServiceReadingMessageBase(object sender, T value)
            : base(sender, value)
        {
        }
    }

    public class AccelerometerServiceReadingMessage : AccelerometerServiceReadingMessageBase<AccelerometerReading>
    {
        public AccelerometerServiceReadingMessage(object sender, AccelerometerReading value)
            : base(sender, value)
        {
        }
    }

    public class AccelerometerShakenMessage : AccelerometerServiceReadingMessageBase<DateTimeOffset>
    {
        public AccelerometerShakenMessage(object sender, DateTimeOffset value)
            : base(sender, value)
        {
        }
    }
}
